package com.hkts.naturalgas.workovertime.service.serviceimpl;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.hkts.naturalgas.flow.VO.FlowNodeinfoOnInstanceInfoVo;
import com.hkts.naturalgas.flow.VO.InitiatorDateTypeVo;
import com.hkts.naturalgas.flow.entity.FlowInstanceinfo;
import com.hkts.naturalgas.flow.mapper.FlowInstanceinfoMapper;
import com.hkts.naturalgas.flow.mapper.FlowNodeinfoMapper;
import com.hkts.naturalgas.performance.entity.HkAssessmentScore;
import com.hkts.naturalgas.utils.CustomPage;
import com.hkts.naturalgas.utils.DateUtils;
import com.hkts.naturalgas.workovertime.VO.HkOvertimeByPageVo;
import com.hkts.naturalgas.workovertime.VO.HkOvertimeInfoNameAndUserNickVo;
import com.hkts.naturalgas.workovertime.entity.HkOvertimeCollect;
import com.hkts.naturalgas.workovertime.entity.HkOvertimeInfo;
import com.hkts.naturalgas.workovertime.mapper.HkOvertimeCollectMapper;
import com.hkts.naturalgas.workovertime.mapper.HkOvertimeDetailMapper;
import com.hkts.naturalgas.workovertime.mapper.HkOvertimeInfoMapper;
import com.hkts.naturalgas.workovertime.service.IHkOvertimeInfoService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import org.springframework.stereotype.Service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.apache.commons.lang.StringUtils;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;

import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author hml
 * @since 2023-08-31
 */
@Service
@Transactional
public class HkOvertimeInfoServiceImpl extends ServiceImpl<HkOvertimeInfoMapper, HkOvertimeInfo> implements IHkOvertimeInfoService {


    @Autowired
    private HkOvertimeInfoMapper hkOvertimeInfoMapper;
    @Autowired
    private FlowInstanceinfoMapper flowInstanceinfoMapper;
    @Autowired
    private HkOvertimeDetailMapper hkOvertimeDetailMapper;
    @Autowired
    private FlowNodeinfoMapper flowNodeinfoMapper;
    @Autowired
    private HkOvertimeCollectMapper hkOvertimeCollectMapper;

    @Override
    public IPage<HkOvertimeInfo> selectPage(Page<HkOvertimeInfo> page, HkOvertimeInfo hkOvertimeInfo) {
        QueryWrapper<HkOvertimeInfo> query = Wrappers.query();
        QueryWrapper<HkOvertimeInfo> entityWrapper = getEntityWrapper(query, hkOvertimeInfo);
        return hkOvertimeInfoMapper.selectPage(page, entityWrapper);
    }


    @Override
    public List<HkOvertimeInfo> selectList(HkOvertimeInfo hkOvertimeInfo) {
        QueryWrapper<HkOvertimeInfo> query = Wrappers.query();
        QueryWrapper<HkOvertimeInfo> entityWrapper = getEntityWrapper(query, hkOvertimeInfo);
        return hkOvertimeInfoMapper.selectList(entityWrapper);
    }

    /**
     * 公共查询条件
     *
     * @param entityWrapper
     * @return
     */
    public QueryWrapper<HkOvertimeInfo> getEntityWrapper(QueryWrapper<HkOvertimeInfo> entityWrapper, HkOvertimeInfo hkOvertimeInfo) {
        //条件拼接
        if (StringUtils.isNotBlank(hkOvertimeInfo.getCreateBy())) {
            entityWrapper.like(HkOvertimeInfo.CREATE_BY, hkOvertimeInfo.getCreateBy());
        }
        if (StringUtils.isNotBlank(hkOvertimeInfo.getUpdateBy())) {
            entityWrapper.like(HkOvertimeInfo.UPDATE_BY, hkOvertimeInfo.getUpdateBy());
        }
        if (StringUtils.isNotBlank(hkOvertimeInfo.getAssessmentName())) {
            entityWrapper.like(HkOvertimeInfo.ASSESSMENT_NAME, hkOvertimeInfo.getAssessmentName());
        }
        if (StringUtils.isNotBlank(hkOvertimeInfo.getAssessmentStatus())) {
            entityWrapper.like(HkOvertimeInfo.ASSESSMENT_STATUS, hkOvertimeInfo.getAssessmentStatus());
        }
        if (StringUtils.isNotBlank(hkOvertimeInfo.getProcessInstanceId())) {
            entityWrapper.like(HkOvertimeInfo.PROCESS_INSTANCE_ID, hkOvertimeInfo.getProcessInstanceId());
        }
        if (StringUtils.isNotBlank(hkOvertimeInfo.getFlowTemplateId())) {
            entityWrapper.like(HkOvertimeInfo.FLOW_TEMPLATE_ID, hkOvertimeInfo.getFlowTemplateId());
        }
        return entityWrapper;
    }

    @Override
    public List<String> getDealtWith(String hontUserId) {
        List<String> list = new ArrayList<String>();
        List<FlowInstanceinfo> backLog = flowInstanceinfoMapper.getBackLog(hontUserId,"2");
        for (int i = 0; i < backLog.size(); i++) {
            list.add(backLog.get(i).getId());
        }
        if (list.size() > 0){
            List<String> pIds = new ArrayList<String>();
            QueryWrapper<HkOvertimeInfo> query = Wrappers.query();
            query.lambda().in(HkOvertimeInfo::getProcessInstanceId,list);
            List<HkOvertimeInfo> hkOvertimeInfos = hkOvertimeInfoMapper.selectList(query);
            hkOvertimeInfos.forEach(hkOvertimeInfo -> {
                pIds.add(hkOvertimeInfo.getProcessInstanceId());
            });
            return pIds;
        }
        return list;
    }
    @Override
    public CustomPage getHkOvertimePageList(HkOvertimeByPageVo hkOvertimeByPageVo){
        CustomPage page = new CustomPage();
        page.setPageNumber(hkOvertimeByPageVo.getPageNumber());
        page.setPageSize(hkOvertimeByPageVo.getPageSize());
        hkOvertimeByPageVo.setFirstRow(page.getFirstRow());
        hkOvertimeByPageVo.setLastRow(page.getLastRow());
        //List<String> dateArray = DateUtils.getDateArray(hkOvertimeByPageVo.getDateType(), hkOvertimeByPageVo.getStartTime(), hkOvertimeByPageVo.getEndTime());
        hkOvertimeByPageVo.setStartTime(DateUtils.startOfTime(hkOvertimeByPageVo.getStartTime()));
        hkOvertimeByPageVo.setEndTime(DateUtils.endOfTime(hkOvertimeByPageVo.getEndTime()));
        List<HkOvertimeInfoNameAndUserNickVo> hkOvertimeInfoAndUserNickNameByProIds = hkOvertimeDetailMapper.getHkOvertimeInfoAndUserNickNameByHkOvertimeByPageVo(hkOvertimeByPageVo);
        long hkOvertimeInfoAndUserNickNameByCount = hkOvertimeDetailMapper.getHkOvertimeInfoAndUserNickNameByCount(hkOvertimeByPageVo);
        page.setTotalRows(hkOvertimeInfoAndUserNickNameByCount);
        List<String> listProcess = new ArrayList<>();
        List<String> processIds = new ArrayList<>();
        hkOvertimeInfoAndUserNickNameByProIds.forEach(hkOvertimeInfoNameAndUserNickVo -> {
            processIds.add(hkOvertimeInfoNameAndUserNickVo.getPid());
            if(hkOvertimeInfoNameAndUserNickVo.getAssessmentStatus().equals("0")){
                listProcess.add(hkOvertimeInfoNameAndUserNickVo.getPid());
            }else if (hkOvertimeInfoNameAndUserNickVo.getAssessmentStatus().equals("1")){
                hkOvertimeInfoNameAndUserNickVo.setNodeName("通过审批");
            }else {
                hkOvertimeInfoNameAndUserNickVo.setNodeName("拒绝审批");
            }
        });
        //计算总用时
        List<InitiatorDateTypeVo> initiatorCountDate = flowInstanceinfoMapper.getInitiatorCountDate(processIds);
        hkOvertimeInfoAndUserNickNameByProIds.stream().map(m -> {
            initiatorCountDate.stream().filter(m2-> Objects.equals(m.getPid(),m2.getId())).forEach(m2-> {
                if (m2.getEndTime() != null){
                    Map<String, Object> datePoorMap = DateUtils.getDatePoorMap(m2.getEndTime(), m2.getStartTime());
                    m.setElapsedTime(datePoorMap.get("elapsedTime").toString());
                }else{
                    m.setElapsedTime("/");
                }
            });
            return m;
        }).collect(Collectors.toList());
        //节点审批人
        if(listProcess.size()>0){
            List<FlowNodeinfoOnInstanceInfoVo> nodeByInstanceIds = flowNodeinfoMapper.getNodeByInstanceIds(listProcess);
            Map<String, String> collect = nodeByInstanceIds.stream().collect(Collectors.toMap(FlowNodeinfoOnInstanceInfoVo::getInstanceId, FlowNodeinfoOnInstanceInfoVo::getNodeName));
            for(int i=0;i<hkOvertimeInfoAndUserNickNameByProIds.size();i++){
                if(collect.containsKey(hkOvertimeInfoAndUserNickNameByProIds.get(i).getPid())){
                    hkOvertimeInfoAndUserNickNameByProIds.get(i).setNodeName(collect.get(hkOvertimeInfoAndUserNickNameByProIds.get(i).getPid()));
                }
            }
        }
        page.setResultData(hkOvertimeInfoAndUserNickNameByProIds);
        return page;
    }

    @Override
    public Map<String,Object> getHkOvertimeInfoCount(HkOvertimeByPageVo hkOvertimeByPageVo){
        hkOvertimeByPageVo.setStartTime(DateUtils.startOfTime(hkOvertimeByPageVo.getStartTime()));
        hkOvertimeByPageVo.setEndTime(DateUtils.endOfTime(hkOvertimeByPageVo.getEndTime()));


        Integer hkOvertimeInfoByCommitCount = hkOvertimeInfoMapper.getHkOvertimeInfoByCommitCount(hkOvertimeByPageVo);

        String hkOvertimeInfoByTotalHours = hkOvertimeInfoMapper.getHkOvertimeInfoByTotalHours(hkOvertimeByPageVo);



        Map<String,Object> resultMap = new HashMap<>();

        resultMap.put("numCount",hkOvertimeInfoByCommitCount);
        if (hkOvertimeInfoByTotalHours == null){
            resultMap.put("totalHours",0);
        }else {
            resultMap.put("totalHours",hkOvertimeInfoByTotalHours);
        }
        if (StringUtils.isNotBlank(hkOvertimeByPageVo.getUserId()) && hkOvertimeByPageVo.getFlowType().equals("3")){
            String yearMonthNum = DateUtils.getYearMonthNum();
            String lastYearMonthNum = DateUtils.getLastYearMonthNum();
            //本月
            QueryWrapper<HkOvertimeCollect> queryWrapper = Wrappers.query();
            queryWrapper.lambda().eq(HkOvertimeCollect::getDateMoth,yearMonthNum)
                    .eq(HkOvertimeCollect::getHontUserId,hkOvertimeByPageVo.getUserId());
            HkOvertimeCollect overtimeCollect = hkOvertimeCollectMapper.selectOne(queryWrapper);

            //上月
            QueryWrapper<HkOvertimeCollect> collectQueryWrapper = Wrappers.query();
            collectQueryWrapper.lambda().eq(HkOvertimeCollect::getDateMoth,lastYearMonthNum)
                    .eq(HkOvertimeCollect::getHontUserId,hkOvertimeByPageVo.getUserId());
            HkOvertimeCollect selectOne = hkOvertimeCollectMapper.selectOne(collectQueryWrapper);

            float t = 0.0f;
            float l = 0.0f;
            if (overtimeCollect != null) {
                t = overtimeCollect.getCurrentmonthSurplusHours();
            }
            if (selectOne != null){
                l = selectOne.getCurrentmonthSurplusHours();
            }
            float c = t + l;
            resultMap.put("plusHours",c);
        }
        return resultMap;
    }
}
